package com.zn.asycn;

import com.alibaba.fastjson.JSONObject;
import com.zn.entity.OptionTradingContract;
import com.zn.entity.OptionTradingGoods;
import com.zn.mapper.OptionTradingContractMapper;
import com.zn.mapper.OptionTradingGoodsMapper;
import com.zn.util.Constant;
import com.zn.util.DateUtils;
import com.zn.util.UUIDUtils;
import com.zn.vo.*;
import com.zn.web.rpc.MdRemoteCall;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author YinJiaWei
 * @version 2018/10/22 10:56
 */
@Component
public class MdAsyncExecutor {
    @Autowired
    private MdRemoteCall mdRemoteCall;
    @Autowired
    private RedisTemplate<String,String> redisTemplate;
    @Autowired
    private OptionTradingGoodsMapper optionTradingGoodsMapper;
    @Autowired
    private OptionTradingContractMapper optionTradingContractMapper;
    private ExecutorService pool = Executors.newCachedThreadPool();
    private static final String ETF_CODE="sh510050";
    @Autowired
    private CalculateKLineExecutor calculateKLineExecutor;
    /**
     * 获取每月行权价 和 合约基础信息
     * @param tg
     * @param date
     */
   /* @Async("executorPool")
    public void executExecAndStat(Integer tg,String date ){
        *//**获取当月行权价 每天执行一次**//*
        Response execResponse=mdRemoteCall.exec(tg, date);
        Object execs=JSONObject.toJSON(execResponse.getExec());
        redisTemplate.opsForValue().set(Constant.TARGETS_DATA_EXECS + tg + ":" + date, execs.toString());
        *//**查询月份的到期日**//*
        Response remainderDay=mdRemoteCall.getSinaRemainderDay(date);
        Integer resultCode=remainderDay.getResult().getStatus().getCode();
        if(resultCode!=null && resultCode==0){
            *//**交割日期**//*
            Object deliveryDay=JSONObject.toJSON(remainderDay.getResult().getData());
            redisPut(Constant.SINA_DATA_DELIVERY_DAY,date,deliveryDay.toString());
        }
        *//**查询合约基础信息**//*
        Response statResponse=mdRemoteCall.stat(tg, date);
        for(HyStatInfo hyStatInfo:statResponse.getStat()){
            Object jsonStat=JSONObject.toJSON(hyStatInfo);
            redisPut(Constant.TARGETS_DATA_STAT + tg + ":" + date, hyStatInfo.getId(), jsonStat.toString());
        }
    }

    @Async("executorPool")
    public void getMdInfoBytargetAndDate(Integer tg,String date){
        Response mdResponse = mdRemoteCall.mdInfo(tg, date);
        Object jsonMd = JSONObject.toJSON(mdResponse.getMd());
        redisTemplate.convertAndSend(Constant.TARGETS_DATA_MDINFO_CHANNEL + tg + ":" + date, jsonMd.toString());
        for (MarketDataField md : mdResponse.getMd()) {
            Object jsonMdInfo = JSONObject.toJSON(md);
            redisPut(Constant.TARGETS_DATA_MDINFO_LIST + tg + ":" + date, md.getId(), jsonMdInfo.toString());
        }

    }

    @Async("executorPool")
    public void getMdInfoBytargetAll(Integer tg){
        Response mdResponse=mdRemoteCall.mdInfo(tg, "");
        Object jsonMd = JSONObject.toJSON(mdResponse.getMd());
        redisTemplate.convertAndSend(Constant.TARGETS_DATA_MDINFO_CHANNEL + tg + ":ALL", jsonMd.toString());
        for (MarketDataField md : mdResponse.getMd()) {
            Object jsonMdInfo = JSONObject.toJSON(md);
            redisPut(Constant.TARGETS_DATA_MDINFO_LIST + tg + ":ALL", md.getId(), jsonMdInfo.toString());
        }
    }

    @Async("executorPool")
    public void getEtfMdInfo(){
        //var hq_str_s_sh510050="50ETF,2.497,-0.028,-1.11,3954492,98046";
        String etfMdInfoApiStr=mdRemoteCall.getEtfMdInfo();
        String [] etfMdInfos=subStringSinaData(etfMdInfoApiStr);
        if(etfMdInfos!=null){
            EtfMdInfo etfMdInfo=new EtfMdInfo(etfMdInfos[0],etfMdInfos[1],etfMdInfos[2],etfMdInfos[3],etfMdInfos[4],etfMdInfos[5]);
            Object jsonMd = JSONObject.toJSON(etfMdInfo);
            redisTemplate.convertAndSend(Constant.ETF_MDINFO_CHANNEL, jsonMd.toString());
            redisPut(Constant.ETF_MDINFO_LIST, ETF_CODE, jsonMd.toString());
        }
    }*/

    @Async("executorPool")
    public void getSinaMdInfo() throws Exception{
//        Set<Object> instrumentCodes=redisTemplate.opsForHash().keys("OPTION-SYMBOL-INFO:2018-11-30");
//        for(Object instrumentCode:instrumentCodes){
            /**
             * varhq_str_CON_OP_10001464="0,0.0000,0.0001,0.0001,10,43558,-50.00,2.2500,0.0002,0.0001,0.1903,0.0001,0.0005,10,0.0004,763,0.0003,524,0.0002,440,0.0001,10,0.0000,0,0.0000,0,0.0000,0,0.0000,0,0.0000,0,2018-10-2314:48:00,0,T01,EBS,510050,50ETF沽10月2250,50.00,0.0002,0.0001,4250,5010.00,M";
             var hq_str_CON_OP_代码=“买量(0)，买价，最新价，卖价，卖量，持仓量，涨幅，行权价，昨收价，开盘价，涨停价，跌停价(11), 申卖 价五，申卖量五，申卖价四，申卖量四，申卖价三，申卖量三，申卖价二，申卖量二，申卖价一，申卖量一，申买价一，申买量一 ，申买价二，申买量二，申买价三，申买量三，申买价四，申买量四，申买价五，申买量五，行情时间，主力合约标识，状态码， 标的证券类型，标的股票，期权合约简称，振幅(38)，最高价，最低价，成交量，成交额
             */
            String content=mdRemoteCall.getSinaMdInfo("10001545");
            String [] sinaMdInfos=subStringSinaData(content);
            if(sinaMdInfos!=null){
                SinaMarketDataField sinaMarketDataField=new SinaMarketDataField(
                        sinaMdInfos[0],sinaMdInfos[1],sinaMdInfos[2],sinaMdInfos[3],
                        sinaMdInfos[4],sinaMdInfos[5],sinaMdInfos[6],sinaMdInfos[7],
                        sinaMdInfos[8],sinaMdInfos[9],sinaMdInfos[10],sinaMdInfos[11],
                        sinaMdInfos[12],sinaMdInfos[13],sinaMdInfos[14],sinaMdInfos[15],
                        sinaMdInfos[16],sinaMdInfos[17],sinaMdInfos[18],sinaMdInfos[19],
                        sinaMdInfos[20],sinaMdInfos[21],sinaMdInfos[22],sinaMdInfos[23],
                        sinaMdInfos[24],sinaMdInfos[25],sinaMdInfos[26],sinaMdInfos[27],
                        sinaMdInfos[28],sinaMdInfos[29],sinaMdInfos[30],sinaMdInfos[31],
                        sinaMdInfos[32],sinaMdInfos[37],sinaMdInfos[39],sinaMdInfos[40],
                        sinaMdInfos[41],sinaMdInfos[42]
                );
                Object jsonMd = JSONObject.toJSON(sinaMarketDataField);
//                System.err.println(instrumentCode+":----->"+sinaMarketDataField.toString());
                //2018-10-2314:48:00
                Date updateTime=DateUtils.convertStringToDate("yyyy-MM-ddHH:mm:ss", sinaMarketDataField.getUpdateTime());
                String minNum=DateUtils.formatDate("HH:mm", updateTime);
                String hashKey="10001545-"+minNum;
//                calculateKLineExecutor.calculateOneMinKLine(hashKey,sinaMarketDataField);
//                calculateKLineExecutor.calculateFiveMinKLine(hashKey,sinaMarketDataField);
//                redisTemplate.convertAndSend(Constant.SINA_DATA_MDINFO_CHANNEL + tg + ":" + date, jsonMd.toString());
//                redisPut(Constant.SINA_DATA_MDINFO_LIST + tg + ":" + date, instrumentCode.toString(), jsonMd.toString());
            }
//        }
    }
//    @Async("executorPool")
//    public void saveTgAndHyDate(Target target,List<HyDate> hyDates){
//        OptionTradingGoods optionTradingGoods=optionTradingGoodsMapper.selectByTgAndName(target.getTg().toString(), target.getName());
//        if(optionTradingGoods==null){
//            optionTradingGoods=new OptionTradingGoods();
//            optionTradingGoods.setTradingGoodsId(UUIDUtils.getUuid());
//            optionTradingGoods.setTradingGoodsCode(target.getTg().toString());
//            optionTradingGoods.setTradingGoodsName(target.getName());
//            optionTradingGoodsMapper.insertSelective(optionTradingGoods);
//        }
//        /**将所有的合约月份设置成 不可交易**/
//        optionTradingContractMapper.setIsTradingDisabled();
//        for(HyDate hyDate:hyDates){
//            OptionTradingContract optionTradingContract=optionTradingContractMapper.selectByGoodsIdAndMonth(optionTradingGoods.getTradingGoodsId(), hyDate.getYm());
//            if(optionTradingContract!=null){
//                //如果存在 则将合约月份设置成可交易
//                optionTradingContract.setIsTrading(0);
//                optionTradingContractMapper.updateByPrimaryKeySelective(optionTradingContract);
//            }else{
//                //如果不存在则新增
//                optionTradingContract=new OptionTradingContract();
//                OptionTradingContract optionTradingContractLast=optionTradingContractMapper.selectLastByGoodsId(target.getTg().toString());
//                if(optionTradingContractLast!=null){
//                    optionTradingContract.setOpenFee(optionTradingContractLast.getOpenFee() == null ? new BigDecimal(0): optionTradingContractLast.getOpenFee());
//                    optionTradingContract.setCloseFee(optionTradingContractLast.getCloseFee()== null ? new BigDecimal(0):optionTradingContractLast.getCloseFee());
//                    optionTradingContract.setCostOpenFee(optionTradingContractLast.getCostOpenFee()== null ? new BigDecimal(0):optionTradingContractLast.getCostOpenFee());
//                    optionTradingContract.setCostCloseFee(optionTradingContractLast.getCostCloseFee()== null ? new BigDecimal(0):optionTradingContractLast.getCostCloseFee());
//                }else{
//                    optionTradingContract.setOpenFee(new BigDecimal(0));
//                    optionTradingContract.setCloseFee(new BigDecimal(0));
//                    optionTradingContract.setCostOpenFee(new BigDecimal(0));
//                    optionTradingContract.setCostCloseFee(new BigDecimal(0));
//                }
//                optionTradingContract.setContractGoodsId(UUIDUtils.getUuid());
//                optionTradingContract.setTradingGoodsId(optionTradingGoods.getTradingGoodsId());
//                optionTradingContract.setContractMonthName(hyDate.getYm());
//                optionTradingContract.setIsTrading(0);
//                optionTradingContract.setCreateTime(new Date());
//                optionTradingContract.setUpdateTime(new Date());
//                optionTradingContractMapper.insertSelective(optionTradingContract);
//            }
//        }
//    }

    public String [] subStringSinaData(String context){
        String [] mdInfoArray=context.split("=");
        if(mdInfoArray.length<2){
            return null;
        }
        String mdInfoElement=mdInfoArray[mdInfoArray.length-1];
        String mdInfoStr=mdInfoElement.substring(1,mdInfoElement.length()-2);
        String [] mdInfos=mdInfoStr.split(",");
        return mdInfos;
    }

    public void redisPut(String key,String id,String value){
        pool.execute(new Thread(() -> {
            redisTemplate.opsForHash().put(key, id, value);
        }));
    }

}
